package org.gluedom.data;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.google.common.base.Function;

class FunctionalHashedComparator<T, V extends Comparable<V>> implements
		Comparator<T> {
	private final Function<T, V> function;

	private FunctionalHashedComparator(Function<T, V> function) {
		assert function != null;
		this.function = function;
	}

	public static <T, V extends Comparable<V>> Comparator<T> fromFunction(
			Function<T, V> function) {
		return new FunctionalHashedComparator<T, V>(checkNotNull(function));
	}

	@Override
	public int compare(T t1, T t2) {
		V c1 = function.apply(checkNotNull(t1));
		V c2 = function.apply(checkNotNull(t2));
		int h1 = c1.hashCode();
		int h2 = c2.hashCode();
		if (h1 != h2)
			return (h1 < h2 ? -1 : 1);
		return c1.compareTo(c2);
	}

	public static <T> T findListEntry(T value, List<? extends T> list,
			Comparator<T> c) {
		int index = Collections.binarySearch(list, value, c);
		return (index < 0 ? null : list.get(index));
	}
}
